﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Lyon.Utility;

namespace Lyon.WinForm
{
    internal partial class RepeatForm : Form
    {
        AsyncThread async = new AsyncThread();

        Callback finished;
        Callback abort;

        public RepeatForm(Callback finished, Callback abort)
        {
            this.finished = finished;
            this.abort = abort;
            InitializeComponent();
        }

        public string Context
        {
            get
            {
                return labelControl1.Text;
            }
            set
            {
                labelControl1.Text = value;
            }
        }

        public void ForEach<T>(IEnumerable<T> collection, Action<T> action)
        {
            List<T> list = new List<T>(collection);
            progressBar1.Minimum = 0;
            progressBar1.Maximum = list.Count + 1;

            async.Start(delegate
            {
                TimeSpan timeRun = TimeSpan.Zero;
                
                for (int i = 0; i < list.Count; i++)
                {
                    DateTime start = DateTime.Now;
                    try
                    {
                        action(list[i]);
                        timeRun += DateTime.Now - start;
                    }
                    catch (System.Threading.ThreadAbortException)
                    {
                        async.Callback(delegate
                        {
                            RunAbort();
                        });
                        return;
                    }
                    catch (Exception ex)
                    {
                        timeRun += DateTime.Now - start;
                        async.Callback(delegate
                        {
                            string message = "执行过程中出现错误.";
                            ExceptionMessageBox.Show(this, ex, message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                            RunAbort();
                        });
                        return;
                    }
                    async.Callback(delegate
                    {
                        this.progressBar1.Value = i + 1;
                        TimeSpan timeLeft = TimeSpan.FromSeconds(timeRun.TotalSeconds / this.progressBar1.Value * (this.progressBar1.Maximum - this.progressBar1.Value));
                        this.Text = String.Format("剩余{0}", DisplayUtility.ToTimeSpan(timeLeft));
                    });

                }
                async.Callback(delegate
                {
                    RunFinished();
                });
            });
        }

        private void RunFinished()
        {
            this.Close();
            if (finished != null)
                try { finished(); }
                catch { }
        }

        private void RunAbort()
        {
            this.Close();
            if (abort != null)
                try { abort(); }
                catch { }
        }
        
        

        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            base.OnFormClosed(e);
            if (BT_Cancel.Enabled)
            {
                BT_Cancel.Enabled = false;
                BT_Cancel.Text = "取消中……";
                if (async.IsStart)
                    async.Stop();
            }
        }

        private void BT_Cancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}
